<?php
/**
 * @desc 助手（点赞/评论）执行队列操作类
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/4
 * Time: 17:11
 */
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Yankewei\LaravelSensitive\Facades\Sensitive;
use Illuminate\Support\Facades\Redis;
use App\Jobs\PushQueue;
use App\Models\Media;
use App\Models\User;
use App\Models\MarketingMediaLike;
use App\Models\MediaComment;
use App\Models\JpushMobile;
use App\Models\UserDynamicList;
use App\Models\MediaCommentConfigLog;
use App\Services\Filter;
use Illuminate\Support\Facades\DB;
use App\Models\ActivityConfig;
use App\Enum\ActivityEnum;
use App\Models\MediaLikeStatic;

class AssistantQueue implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $params;
    protected $page_size = 100; // 每页数量需要和生成队列的统一[assistant]

    /**
     * Create a new job instance.
     * @param $params
     * @return void
     */
    public function __construct($params)
    {
        $this->params = $params;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $action = $this->params['action'];
        $config_data = $this->params['data'];
        $this->$action($config_data);

        return true;
    }

    /**
     * @desc 执行视频点赞队列
     * @param $config
     * @return bool
     */
    public function media_like_queue($config)
    {
        // 判断视频是否有效
        $media = $this->params['media'];
        $where_arr = ['is_delete' => 0, 'is_private' => 0, 'is_forward' => 0, 'status' => 1, 'id' => $media['id']];
        $media_info = Media::where($where_arr)->first();
        if(empty($media_info)) {
            return true;
        }

        // 校验视频为活动视频且在活动有效期内
        $current_time = time();
        $has_activity = false;
        if($media['is_participate_activity'] == 1) {
            $activity_info = ActivityConfig::where(['status' => ActivityEnum::ACTIVITY_STATUS_VALID, 'activity_type' => ActivityEnum::ACTIVITY_TYPE_LIKE])->first();
            if($activity_info) {
                if(($activity_info->start_time < $current_time) && ($activity_info->end_time > $current_time)) {
                    $has_activity = true;
                }
            }
        }

        // 获取运营账号及统计运营账号总数
        $user_list = User::where(['role' => 3, 'status' => 1])->skip(0)->take($config['account_num'])->get()->toArray();
        if(empty($user_list)) {
            return true;
        }
        $user_count = count($user_list); // 营销账号总数

        // 每个视频的点赞总数 = 营销账号数 * 频率
        $additional_like = $config['frequency'] * $user_count;

        DB::beginTransaction();
        try{
            // 视频追加赞数
            $rs = Media::where(['id' => $media['id']])->increment('like', $additional_like);
            if(!$rs) {
                throw new \Exception('视频ID【'.$media['id'].'】在视频表追加赞异常');
            }

            // 判断否存在活动
            if($has_activity) {
                // 周统计
                $static_week_where = ['type' => 1,'date_format' => date('W', $current_time),'uid' => $media['uid']];
                $static_week_record = MediaLikeStatic::where($static_week_where)->first();
                if($static_week_record) {
                    $week_static_rs = MediaLikeStatic::where($static_week_where)->increment('like_num', $additional_like);
                } else {
                    $week_static_data = [
                        'activity_id' => $activity_info->id,
                        'type' => 1,
                        'date_format' => date('W', $current_time),
                        'uid' => $media['uid'],
                        'create_time' => $current_time,
                        'update_time' => $current_time,
                        'like_num' => $additional_like
                    ];
                    $week_static_rs = MediaLikeStatic::insert($week_static_data);
                }

                if(!$week_static_rs) {
                    throw new \Exception('写入周统计失败【'.$media['id'].'】');
                }

                // 月统计
                $static_month_where = ['type' => 2, 'date_format' => date('Ym', $current_time),'uid' => $media['uid']];
                $static_month_record = MediaLikeStatic::where($static_month_where)->first();
                if($static_month_record) {
                    $month_static_rs = MediaLikeStatic::where($static_month_where)->increment('like_num', $additional_like);
                } else {
                    $month_static_data = [
                        'activity_id' => $activity_info->id,
                        'type' => 2,
                        'date_format' => date('Ym', $current_time),
                        'uid' => $media['uid'],
                        'create_time' => $current_time,
                        'update_time' => $current_time,
                        'like_num' => $additional_like
                    ];
                    $month_static_rs = MediaLikeStatic::insert($month_static_data);
                }
                if(!$month_static_rs) {
                    throw new \Exception('写入周统计失败【'.$media['id'].'】');
                }
            }

            // 记录每个营销账号的点赞记录
            $media_list_log = [];
            foreach($user_list as $user) {
                $media_list_log[] = [
                    'uid' => $user['id'],
                    'media_id' => $media['id'],
                    'media_uid' => $media['uid'],
                    'status' => 1,
                    'praise_points' => $config['frequency'],
                    'config_id' => $config['id'],
                    'created_at' => time2date($current_time),
                    'updated_at' => time2date($current_time),
                    'is_participate_activity' => $has_activity ? 1 : 0,
                ];

            }
            $log_rs = MarketingMediaLike::insert($media_list_log);
            if(!$log_rs) {
                throw new \Exception('添加日志异常【'.$media['id'].'】');
            }

            DB::commit();
        } catch(\Exception $e) {
            DB::rollback();
            // 异常信息写入Mongodb
            $params = [['type' => 'assistant_like', 'status' => 'error', 'params'=> json_encode($this->params), 'content' => $e->getMessage(), 'created_at' => time2date()]];
            insert_mongodb_log('assistant_like', $params);
            return false;
        }
    }

    /**
     * @desc 执行视频评论队列
     * @param $config
     * @return bool
     */
    public function media_comment_queue($config)
    {
        // 获取营销账号（只获取一个营销账号）
        $user_info = User::where(['role' => 3, 'status' => 1])->first(['id']);
        if(empty($user_info)) {
            return true;
        }
        $user_info = $user_info->toArray();

        $where_arr = ['is_delete' => 0];
        if($config['media_type'] == 1) {
            $where_arr['is_private'] = 0;
            $where_arr['is_forward'] = 0;
            $where_arr['status'] = 1;
        } else {
            return true;
        }

        $fields = ['id', 'uid', 'cover'];
        for($i=$this->params['start_page'];$i<=$this->params['end_page'];$i++) {
            $offset = ($i - 1) * $this->page_size;
            $media_list = Media::where($where_arr)->skip($offset)->take($this->page_size)->orderBy('id', 'ASC')->get($fields)->toArray();
            if(empty($media_list)) {
                return true;
            }

            foreach($media_list as $media) {
                // 过滤已评论过的
                $log_where = ['config_id' => $config['id'], 'media_id' => $media['id'], 'uid' => $user_info['id'], 'execution_time' => $config['execution_time']];
                if(MediaCommentConfigLog::where($log_where)->first(['id'])) {
                    continue;
                }

                // 写入评论表、增加评论数、写入动态
                $params = ['media_id' => $media['id'], 'media_uid' => $media['uid'], 'comment_uid' => $user_info['id'], 'comment_content' => $config['comment_content'], 'cover' => $media['cover']];
                if(!$this->_comment_media($params)) {
                    continue;
                }
                // 发送红点
                $this->_comment_push_channel($params);

                $log_data = [
                    'config_id' => $config['id'],
                    'media_id' => $media['id'],
                    'uid' => $user_info['id'],
                    'comment_content' => $config['comment_content'],
                    'execution_time' => $config['execution_time'],
                    'created_at' => time(),
                    'updated_at' => time()
                ];

                MediaCommentConfigLog::insert($log_data);   // 记录日志
            }
        }
        return true;
    }

    /**
     * @desc 评论视频内容
     * @param $params
     * @return bool
     */
    private function _comment_media($params)
    {
        $comment_content = $this->_filter_comment_content($params['comment_content']); // 敏感词过滤

        DB::beginTransaction();
        // 视频的评论数增加1
        $rs = Media::where(['id' => $params['media_id']])->increment('comments', 1);
        if(!$rs) {
            DB::rollBack();
            return false;
        }

        // 视频添加评论
        $comment_data = [
            'uid' => $params['comment_uid'],
            'reply_uid' => 0,
            'media_id' => $params['media_id'],
            'parent_id' => 0,
            'relation_id' => '',
            'content' => $comment_content,
            'type' => 0,
            'created_at' => time2date(),
            'updated_at' => time2date(),
        ];
        $comment_id = MediaComment::insertGetId($comment_data);
        if(!$comment_id) {
            DB::rollBack();
            return false;
        }


        // 视频发布者动态
        $user_dynamic_data = [
            'uid' => $params['media_uid'],
            'type' => 1,
            'operation_id' => $comment_id,
            'parent_id' => 0,
            'option_uid' => $params['comment_uid'],
            'media_id' => $params['media_id'],
            'option_other' => $params['cover'],
            'option_content' => $comment_content,
            'create_time' => time(),
            'update_time' => time()
        ];

        $dynamic_rs = UserDynamicList::insert($user_dynamic_data);
        if(!$dynamic_rs) {
            DB::rollBack();
            return false;
        }
        DB::commit();
        return true;
    }

    /**
     * @desc 过滤敏感词
     * @param $comment_content
     * @return mixed
     */
    private function _filter_comment_content($comment_content)
    {
        $interference = ['&', '*'];
        $filename = config_path().'/sensitiveword.txt'; //每个敏感词独占一行
        Sensitive::interference($interference); //添加干扰因子
        Sensitive::addwords($filename); //需要过滤的敏感词
        $filter_content = Sensitive::filter($comment_content);
        $filter_content = Filter::init($filter_content);
        return $filter_content;
    }

    /**
     * @desc 给视频发布者推送评论信息
     * @param $params
     * @return bool
     */
    private function _comment_push_channel($params)
    {
        $user_info = D('users')->find($params['media_uid']);
        if ($user_info && $user_info->registration_id){

            $getPushChannel = JpushMobile::getRowsArray([['registration_id', '=', $user_info->registration_id]]);
            // 消息推送
            if(!empty($getPushChannel) && !empty($getPushChannel['push_channel_id'])){

                $notifyContent = trans('notice.10213'); // '其他用户评论了您发布的视频';

                ////////////////////////////////////////////////////////////////////////////////////////////////
                // 标题  --app 通过notify id 0处理业务 --透传
                $data = [];
                $push_channel_key = 'jpush';
                if($getPushChannel['push_channel_id'] == 2){
                    $push_channel_key = 'hpush';
                }else if($getPushChannel['push_channel_id'] == 3){
                    $push_channel_key = 'xmpush';
                }

                $data['channel_id'] = $getPushChannel['push_channel_id'];
                $data['title'] = trans('notice.10215'); // '评论/回复';
                $data['content'] = $notifyContent; // 内容
                $data['description'] = $notifyContent; // 描述
                $data['msg_type'] = config('push')[$push_channel_key]['type']['ospf'];  // 消息类型：1通知 0透传
                $data['notify_id'] = 2;     // 通知id   --app 处理业务标识
                $data['notify_foreground'] = 0; // 开启/关闭app在前台时的通知弹出 1:弹出通知  0 不弹出
                $data['mobile_list'] = $getPushChannel['registration_id'];
                dispatch((new PushQueue(['type'=>'singlePush', 'data'=>$data]))->onQueue('push'));
                ////////////////////////////////////////////////////////////////////////////////////////////////
            }
        }

        return true;
    }
}
